package com.woniu.woniu_bx.controller;

import com.woniu.woniu_bx.exception.TooPoorException;
import com.woniu.woniu_bx.pojo.Order;
import com.woniu.woniu_bx.pojo.PageBean;
import com.woniu.woniu_bx.pojo.ResponseEntity;
import com.woniu.woniu_bx.pojo.User;
import com.woniu.woniu_bx.service.OrderService;
import com.woniu.woniu_bx.service.UserService;
import com.woniu.woniu_bx.utils.OssManagerUtil;
import com.woniu.woniu_bx.utils.RandomUtil;
import com.woniu.woniu_bx.utils.SendSms;
import com.woniu.woniu_bx.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.parameters.P;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author : 王泰元
 * @className: UserController
 * @description: TODO
 * @date : 2022/8/29 12:24
 */
@RestController
@Validated
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 注册（添加）用户，service 层的方法中进行了密码加密、设置注册时间、账户唯一性等操作
     *
     * @param user 用户
     * @return 操作成功响应
     */
    @PostMapping("/user/register")
    public ResponseEntity register(@RequestBody User user) {
        log.debug("user : {}", user);
        userService.addUser(user);
        return ResponseEntity.SUCCESS("注册成功", user);
    }


    /**
     * <p>动态更新用户信息，其中账户、生日、性别、注册时间不可修改，传入这些数据无效</p>
     * <p>注意：用户 id 不可为空，否则将会导致无效参数异常</p>
     * <p>如：仅需修改密码，可传入只有 id 和 password 属性的 user，其他属性为空，则只修改密码</p>
     *
     * @param user 用户
     * @return 操作成功响应
     */
    @PostMapping("/user/update")
    public ResponseEntity update(@RequestBody User user) {
        userService.updateByCondition(user);
        return ResponseEntity.SUCCESS("修改成功", userService.getById(user.getId()));
    }

    /**
     * <p>只会更新用户的昵称、生日、个性签名、头像，其他的数据传入无效，避免前端传入账号余额，来达到非法目的
     *
     * @param user 用户
     * @return 操作成功响应
     */
    @PostMapping("/user/updateBase")
    public ResponseEntity updateBase(@RequestBody User user) {
        if(user.getUserImages()!=null){
            userService.addUserImg(user.getId(),user.getUserImages());
            user.setUserImages(null);
        }
        userService.updateUserBaseInfo(user);
        return ResponseEntity.SUCCESS("修改成功", null);
    }


    /**
     * 根据 id 改变 user 状态，将状态设为 n（锁定） 或解锁用户（y）
     *
     * @param id 用户 id
     * @return 操作成功响应
     */
    @GetMapping("/admin/user/updateStatus")
    @PreAuthorize("hasAnyAuthority('user:lock')")
    public ResponseEntity delete(@NotNull Integer id, @NotNull String status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        userService.updateByCondition(user);
        return ResponseEntity.SUCCESS("操作成功", null);
    }


    /**
     * 前端传递图片url地址集合，存入数据库
     *
     * @param userVo
     * @return 操作成功响应
     */
    @PostMapping("/user/authPw/submit")
    public ResponseEntity subAuthPw(@RequestBody UserVo userVo) {
        log.debug("userVo； {}", userVo);
        // 保存图片地址
        List<String> imgList = userVo.getImgList();
        userService.addUserImg(userVo.getUser().getId(), imgList);
        // 更改用户信息
        User user = new User();
        user.setId(userVo.getUser().getId());
        user.setAuthPw("c");
        userService.updateByCondition(user);
        return ResponseEntity.SUCCESS("提交成功", null);
    }


    /**
     * 后台：通过用户提交的陪玩认证
     *
     * @param id 用户id
     * @return 操作成功响应
     */
    @GetMapping("/admin/user/authPw/agree")
    @PreAuthorize("hasAnyAuthority('pw:pass')")
    public ResponseEntity agreeAuthPw(@NotNull Integer id) {
        User user = new User();
        user.setId(id);
        user.setAuthPw("y");
        userService.updateByCondition(user);
        return ResponseEntity.SUCCESS("通过陪玩认证成功", null);
    }


    /**
     * 后台：拒绝用户提交的陪玩认证
     *
     * @param id 用户id
     * @return 操作成功响应
     */
    @GetMapping("/admin/user/authPw/refuse")
    @PreAuthorize("hasAnyAuthority('pw:unpass')")
    public ResponseEntity refuseAuthPw(@NotNull Integer id) {
        User user = new User();
        user.setId(id);
        user.setAuthPw("n");
        userService.updateByCondition(user);
        return ResponseEntity.SUCCESS("拒绝陪玩认证成功", null);
    }


    /**
     * <p>多条件分页查询用户</p>
     * <p>因为get方法无请求体，此处多条件查询需解析json字符串，需要请求体，所以为post</p>
     *
     * @param userVo 封装了 User user 、Integer pageNum 的 ViewObject
     * @return 封装了 User类数据的 PageBean 的 ResponseEntity
     */
    @PostMapping("/admin/user/list")
    @PreAuthorize("hasAnyAuthority('user:list')")
    public ResponseEntity<PageBean<User>> list(
            @RequestBody UserVo userVo) {
        log.debug("userVo : {}", userVo);

        // 每页展示条数，暂定 10
        Integer pageSize = 10;

        User user = userVo.getUser();
        Integer pageNum = userVo.getPageNum() == null ? 1 : userVo.getPageNum();
        PageBean<User> pageBean = userService.getByPage(user, pageNum, pageSize);
        return ResponseEntity.SUCCESS("ok", pageBean);
    }


    /**
     * 根据 id 查询用户
     *
     * @param id 用户 id
     * @return 操作成功响应
     */
    @GetMapping("/user/byId")
    public ResponseEntity<User> getById(@NotNull Integer id) {
        User user = userService.getById(id);
        List<String> userImages = userService.getUserImagesById(id);
        user.setUserImages(userImages);
        return ResponseEntity.SUCCESS("ok", user);
    }


    /**
     * 根据账号查询用户，用于判断用户是否存在等
     *
     * @param account 用户账户
     * @return 操作成功响应
     */
    @GetMapping("/user/byAccount")
    public ResponseEntity<User> getByAccount(@NotNull String account) {
        return ResponseEntity.SUCCESS("ok", userService.getByAccount(account));
    }


    /**
     * <p>根据用户 id 查询其关注列表，为简化查询，其中查询出来的用户数据只包含id、昵称、头像</p>
     * <p>如需关注用户的详细信息，可根据 id 再次调用 <tt>/user/byId</tt> 查询</p>
     *
     * @param id 用户 id
     * @return 封装了用户集合的 ResponseEntity
     */
    @GetMapping("/user/getLikes")
    public ResponseEntity<List<User>> getLikes(@NotNull Integer id) {
        List<User> likes = userService.getLikesById(id);
        return ResponseEntity.SUCCESS("ok", likes);
    }

    /**
     * 获取互相关注
     *
     * @param id
     * @return
     */
    @GetMapping("/user/getLikesEach")
    public ResponseEntity<List<User>> getLikesEach(@NotNull Integer id) {
        List<User> likes = userService.getLikesEachById(id);
        return ResponseEntity.SUCCESS("ok", likes);
    }

    /**
     * <p>根据用户 id 查询其粉丝列表，为简化查询，其中查询出来的用户数据只包含id、昵称、头像</p>
     * <p>如需粉丝用户的详细信息，可根据 id 再次调用 <tt>/user/byId</tt> 查询</p>
     *
     * @param id 用户 id
     * @return 封装了用户集合的 ResponseEntity
     */
    @GetMapping("/user/getFans")
    public ResponseEntity<List<User>> getFans(@NotNull Integer id) {
        List<User> fans = userService.getFansById(id);
        return ResponseEntity.SUCCESS("ok", fans);
    }

    @GetMapping("/user/getFansEach")
    public ResponseEntity<List<User>> getFansEach(@NotNull Integer id) {
        List<User> fans = userService.getFansEachById(id);
        return ResponseEntity.SUCCESS("ok", fans);
    }

    /**
     * 获取自己的关注数
     *
     * @param id
     * @return
     */
    @GetMapping("/user/getLikesCount/{id}")
    public ResponseEntity<Integer> getLikesCount(@PathVariable Integer id) {
        Integer count = userService.getLikesCount(id);
        return ResponseEntity.SUCCESS("ok", count);
    }

    /**
     * 获取自己的粉丝数
     *
     * @param id
     * @return
     */
    @GetMapping("/user/getFansCount/{id}")
    public ResponseEntity<Integer> getFansCount(@PathVariable Integer id) {
        Integer count = userService.getFansCount(id);
        return ResponseEntity.SUCCESS("ok", count);
    }

    /**
     * 获得用户陪玩图片
     *
     * @param id
     * @return
     */
    @GetMapping("/user/getUserImages")
    public ResponseEntity<List<String>> getUserImages(@NotNull Integer id) {
        List<String> userImages = userService.getUserImagesById(id);
        return ResponseEntity.SUCCESS("ok", userImages);
    }

    /**
     * 点击关注的时候调用该接口
     *
     * @param myId    我的id，你关注别人肯定需要传自己的id
     * @param otherId 被关注者的id
     * @return
     */
    @GetMapping("/user/careSomebody/{myId}/{otherId}")
    public ResponseEntity careSomebody(@PathVariable Integer myId, @PathVariable Integer otherId) {
        log.debug("我的id:{},我关注的id：{}", myId, otherId);
        userService.careSomebody(myId, otherId);
        return ResponseEntity.SUCCESS("关注成功", null);
    }

    /**
     * 发生取消关注事件时调用该接口
     *
     * @param myId
     * @param otherId
     * @return
     */
    @GetMapping("/user/cancelCare/{myId}/{otherId}")
    public ResponseEntity cancelCare(@PathVariable Integer myId, @PathVariable Integer otherId) {
        log.debug("我的id:{},我取关的id：{}", myId, otherId);
        userService.cancelCare(myId, otherId);
        return ResponseEntity.SUCCESS("取关成功", null);
    }

    /**
     * 修改密码
     *
     * @param userVo
     * @return
     */
    @PostMapping("/user/updatePwd")
    public ResponseEntity updatePwd(@RequestBody UserVo userVo) {
        User user = userVo.getUser();
        userService.updateUserPwd(user.getId(), user.getPassword(), userVo.getNewPwd());
        return ResponseEntity.SUCCESS("修改成功", null);
    }

    /**
     * 修改用户头像
     *
     * @param user
     * @return
     */
    @PostMapping("/user/changeAvr")
    public ResponseEntity changeAvr(@RequestBody User user) {
        // 删除之前保存的图片
        User realUser = userService.getByAccount(user.getAccount());
        OssManagerUtil.delShopImage(realUser.getAvr());
        userService.updateById(user);
        return ResponseEntity.SUCCESS("更换图片成功", user);
    }

    /**
     * 增加陪玩图片
     *
     * @param userVo
     * @return
     */
    @RequestMapping("/user/addPwImg")
    public ResponseEntity addPwList(@RequestBody UserVo userVo) {

        // 根据前端传过来的id查询用户
        User user = userService.getById(userVo.getUser().getId());

        // 保存图片地址
        List<String> imgList = userVo.getImgList();
        userService.addUserImg(userVo.getUser().getId(), imgList);
        return ResponseEntity.SUCCESS("增加陪玩图片成功", null);
    }

    /**
     * pw提现
     *
     * @param id
     * @return
     */
    @RequestMapping("/user/withdrawPwMoney")
    public ResponseEntity withdrawPwMoney(@NotNull Integer id) {
        // 根据前端传过来的id查询用户
        User user = userService.getById(id);
        //flag = -1,表示bigdemical1小于bigdemical2；
        //flag = 0,表示bigdemical1等于bigdemical2；
        //flag = 1,表示bigdemical1大于bigdemical2；
        int flag = user.getMoney().compareTo(new BigDecimal(0));
        if (flag > 0) {
            // 余额大于0
            userService.withdrawPwMoney(id);
        } else if (flag <= 0) {
            throw new TooPoorException("账户余额不足，无法体现");
        }
        return ResponseEntity.SUCCESS("陪玩提现成功", null);
    }

    @RequestMapping("/user/getAllOrderMoney")
    public ResponseEntity getAllOrderMoneyByUid(@NotNull Integer uid) {
        return ResponseEntity.SUCCESS("ok", userService.getAllOrderMoneyByUid(uid));
    }

    @RequestMapping("/user/showOrderList")
    public ResponseEntity<List<Order>> showOrderList(@RequestBody UserVo userVo) {
        // 根据前端传过来的id查询用户
        User user = userService.getById(userVo.getUser().getId());
        // 陪玩才能查看订单列表
        if (user.getAuthPw().equalsIgnoreCase("y")) {
            List<Order> orderList = orderService.getByPwUserId(userVo.getUser().getId());
            return ResponseEntity.SUCCESS("ok", orderList);
        } else {
            throw new RuntimeException("不是陪玩，无权查看");
        }
    }


    // 发送短信验证码
    @GetMapping("/sendCaptcha")
    public ResponseEntity sendCaptcha(@NotNull String telephone) throws ExecutionException, InterruptedException {
        String captcha = RandomUtil.getVerrityCode();

        // 发送短信
        SendSms.sendMessage(telephone, captcha);

        // 验证码保存
        redisTemplate.opsForValue().set(telephone + "_captcha", captcha, 60, TimeUnit.SECONDS);

        log.debug("缓存中的验证码: {}", redisTemplate.opsForValue().get(telephone + "_captcha"));

        return ResponseEntity.SUCCESS("发送成功", null);
    }

    /**
     * 获取是否关注对方
     * @param myId
     * @param openUserId
     * @return
     */
    @GetMapping("/user/careUser/{myId}/{openUserId}")
    public ResponseEntity careUser(@PathVariable Integer myId,@PathVariable Integer openUserId){
        return ResponseEntity.SUCCESS("查询关注成功",userService.careUser(myId,openUserId));
    }
}
